package it.univpm.diiga.memorysim.actions;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

import it.univpm.diiga.memorysim.data.DataPlugin;
import it.univpm.diiga.memorysim.data.Record;
import it.univpm.diiga.memorysim.kernel.shared.tree.File;
import it.univpm.diiga.memorysim.kernel.shared.tree.MovingBox;
import it.univpm.diiga.memorysim.views.MemorySecondaryInitialSituation;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;


public class Load implements IWorkbenchWindowActionDelegate {
	public static IWorkbenchWindow window;
	public static boolean codaprocessi=false;
	private Record rec;
	private boolean[]report= new boolean[]{true,true,true,true,true,true,true,true};

	public Load() {
	}


	public void run(IAction action) {
	    FileDialog dialog = new FileDialog(window.getShell(), SWT.SEARCH);
	    dialog
	        .setFilterNames(new String[] { "Batch Files", "All Files (*.*)" });
	    dialog.setFilterExtensions(new String[] { "*.bin", "*.*" }); // Windows
	                                    // wild
	                                    // cards
	    dialog.setFilterPath(Platform.getLocation()+""); // Windows path
		    try{ 
	            FileInputStream fis = new FileInputStream(dialog.open()); 
	            ObjectInputStream ois = new ObjectInputStream(fis); 
	            rec = (Record) ois.readObject(); 
	            fis.close();
	        	DataPlugin.reset();
	       		SelectSimulation(rec.getsimulation());
	    		Parameter(rec.getparameter());
	    		paginazione(rec.getListDimProcess());
	    		segmentazione(rec.getListNumSeg());
	    		seqsim(rec.getProcreq());
	    		memcentral(rec.getInitRAM(),rec.getInitSWAP());
	    		filerequest(rec.getFileRequest());
	    		initHDD(rec.getFileSystem());
	    		//rec.Stamp();
	    		PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().resetPerspective();
	    		Report();
		    } 
	        catch(Exception a){ }    
	}


	private void Report() {
		String val="";
		if(report[0]) val+="Tipo di Simulazione\n";
		if(report[1]) val+="Caratteristiche dell'hardware\n";
		if(report[2]) val+="Lista dei processi\n";
		if(report[3]) val+="Lista di Segmenti\n";
		if(report[4]) val+="Sequenza di Simulazione della memoria centrale\n";
		if(report[5]) val+="Situazione Iniziale Memoria Centrale\n";
		if(report[6]) val+="Lista di Operazioni sui file\n";
		if(report[7]) val+="Situazione Iniziale Memoria Secondaria\n";
		if(val.equals(""))MessageDialog.openInformation(window.getShell(),"Loading","Nessun Valore caricato");
		else MessageDialog.openInformation(window.getShell(),"Loading","Valori Caricati:\n"+val);
		
	}


	private void initHDD(String system) {
     try{
 		try {
			 window.getActivePage().showView(MemorySecondaryInitialSituation.ID, "Gestione HardDisk", IWorkbenchPage.VIEW_ACTIVATE);
		} catch (PartInitException e1) {
			MessageDialog.openError(window.getShell(), "Error", "Error opening view:" + e1.getMessage());
		}
		String[] files = system.split(",");
		if(files.length<2)  report[7]=false;
		else report[7]=true;
		MovingBox disco = new MovingBox();
		boolean file=false;
		boolean neew;
		for(int i=0;i<files.length;i++){
			MovingBox cursor=DataPlugin.root;
			String[] element = (files[i].substring(1)).split("/");
			for(int j=0;j<element.length;j++){
						String nome="";
						file=false;
						neew=true;
					String[] isfile = element[j].split("\\.");
						if(isfile.length==2){
							file=true;
							nome=isfile[0].substring(0,isfile[0].length()-1);
							neew=readyWrite(cursor, nome);
						}
						if(isfile.length==1){
							nome=isfile[0];
							neew=readyWrite(cursor,nome);
						}
					if(file && !neew){
						File f =  new File(nome);
						f.dimensione=Integer.parseInt(isfile[1]);
						cursor.add(f);
					}
					if(!file && !neew){
						MovingBox dir = new MovingBox(nome);
						cursor.add(dir);
					}
					int index=findDir(cursor,nome);
					cursor=(MovingBox) cursor.getBoxes().get(index);
			}
		}
		
	 for(int i=0;i<disco.getBoxes().size();i++){
		 ((MovingBox)DataPlugin.root.getBoxes().get(0)).add((MovingBox) disco.getBoxes().get(i));
	 }
	 
     }catch(Exception e1){}
	}

	
	private void memcentral(String initRAM, String initSWAP) {
		try{
		if(initRAM.equals("") && initSWAP.equals("")) report[5]=false;
		DataPlugin.CentralMemoryP=new ArrayList<String>();
		DataPlugin.SwapMemoryP=new ArrayList<String>();
		String[] ram=initRAM.split(",");
		String[] swap=initSWAP.split(",");
		for(String mem: ram) {
			if(mem.equals("null")) mem="                       ";
			DataPlugin.CentralMemoryP.add(mem);
		}
		for(String mem1: swap){
			if(mem1.equals("null")) mem1="                       ";
			DataPlugin.SwapMemoryP.add(mem1);
		}
		}catch(Exception e){report[5]=false;}
	}


	private void filerequest(String[] fileRequest) {
		try{
			DataPlugin.newFileListRequest();
			String[] nomi=fileRequest[0].split(",");
			String[] dims=fileRequest[1].split(",");
			String[] paths=fileRequest[2].split(",");
			String[] operazioni=fileRequest[3].split(",");
			if(nomi.length<1) report[6]=false;
			else{
				if(nomi[0].equals("")) report[6]=false;
			}
			for(int i=0;i<nomi.length;i++){
				int dim=Integer.parseInt(dims[i]);
				DataPlugin.addFileRequest(nomi[i], dim, paths[i], operazioni[i]);
			}
		}catch(Exception e){}
	}


	private void seqsim(String procreq) {
	  try{
		DataPlugin.newProcessRequest();
		String[] listreq=procreq.split(",");
		for(int i=0;i<listreq.length;i++){
			String[] dato=listreq[i].split("-");
			int proc=Integer.parseInt(dato[0]);
			int pOs=Integer.parseInt(dato[1]);
			String type=dato[2];
			int dim=Integer.parseInt(dato[3]);
			if(dim>0){DataPlugin.addProcessRequest(proc, pOs,type,dim);}
			else{DataPlugin.addProcessRequest(proc, pOs,type);}
		}
	  }catch(Exception e){report[4]=false;}
		
	}


	private void segmentazione(String listNumSeg) {
	  try{
		String[] num=listNumSeg.split(",");
		for(int i=0;i<num.length;i++){
			DataPlugin.listSegmentP.add(Integer.parseInt(num[i]));
		}
	  }catch(Exception e){report[3]=false;}
	}


	private void paginazione(String listDimProcess) {
	  try{
		String[]dims=listDimProcess.split(",");
		for(int i=0;i<dims.length;i++){
			DataPlugin.addProcess(i+1, Integer.parseInt(dims[i]));
		}
	  }catch(Exception e){report[2]=false; }
	}


	private void SelectSimulation(String sim) {
	  try{
		
		String[] types= sim.split(",");
		DataPlugin.SimType=Integer.parseInt(types[0]);
		if(DataPlugin.SimType==0) report[0]=false;
		DataPlugin.SimSelected=types[1];
		DataPlugin.SimSelected1=types[2];
		DataPlugin.AlgSelected=types[3];
		it.univpm.diiga.memorysim.views.SelectSimulation.addLoader();
	  }catch(Exception e){report[0]=false;}
	}

	public void Parameter(String param){
	  try{
		
		String[] types= param.split(",");
		DataPlugin.memorycentraldata=Integer.parseInt(types[0]);
		if(DataPlugin.memorycentraldata==0) report[1]=false;
		DataPlugin.swapdata=Integer.parseInt(types[1]);
		DataPlugin.blockdata=Integer.parseInt(types[2]);
		DataPlugin.hdddimensionblockdata=Integer.parseInt(types[3]);
		DataPlugin.trasferratedata=Integer.parseInt(types[4]);
		DataPlugin.seekdata=Integer.parseInt(types[5]);
		DataPlugin.hdddimensiondata=Integer.parseInt(types[6]);
		DataPlugin.revolutiontimedata=Integer.parseInt(types[7]);
		DataPlugin.hddused=Integer.parseInt(types[8]);
		DataPlugin.ramUsed=Integer.parseInt(types[9]);
	  }catch(Exception e){report[1]=false;}
	}

	
	private int findDir(MovingBox dir, String nome){
		int id=-1;
		for(int i=0;i<dir.getBoxes().size();i++){
			MovingBox selected = (MovingBox) dir.getBoxes().get(i);
			if(nome.equals(selected.getTitle()) || nome.equals(selected.getName())) id=i;
		}
		return id;
	}
	
	private boolean readyWrite(MovingBox dir, String nome) {
		boolean result = false;
		for(int i=0;i<dir.getBoxes().size();i++){
			MovingBox selected = (MovingBox) dir.getBoxes().get(i);
			if(nome.equals(selected.getTitle()) || nome.equals(selected.getName())) result=true;
		}
		return result;
	}
	
	
	
	
	public void selectionChanged(IAction action, ISelection selection) {
	}


	public void dispose() {
	}

	@SuppressWarnings("static-access")
	public void init(IWorkbenchWindow window) {
		this.window = window;
	}
	
}